#include "World.h"

using namespace std;
using namespace me;

World::World(string name, Vector2f size, Vector2f tileSize, cpVect gravity): m_name(name), m_size(size), m_tileSize(tileSize)
{
    m_space = cpSpaceNew();
    cpSpaceSetGravity(m_space, gravity);


    m_borders[0] = cpSegmentShapeNew(m_space->staticBody, cpv(0,0), cpv(m_size.x, 0), 0);
    m_borders[2] = cpSegmentShapeNew(m_space->staticBody, cpv(m_size.x,0), cpv(size.x, size.y), 0);
    m_borders[1] = cpSegmentShapeNew(m_space->staticBody, cpv(0,0), cpv(0, m_size.y), 0);
    m_borders[3] = cpSegmentShapeNew(m_space->staticBody, cpv(0,m_size.y), cpv(m_size.x, m_size.y), 0);

    for (int i=0 ; i < 4 ; i++)
	{
		cpShapeSetFriction(m_borders[i], 1);
		cpSpaceAddShape(m_space, m_borders[i]);
	}
}

World::~World()
{
	cpSpaceFree(m_space);
    for (int i=0 ; i < 4 ; i++)
		cpShapeFree(m_borders[i]);
	for (unsigned int i=0 ; i < m_entities.size() ; i++)
    {
        if (m_entities[i] != NULL)
            delete m_entities[i];
    }
}


void World::update()
{
	cpFloat timeStep = 1.0f/60.0f;
	cpSpaceStep(m_space, timeStep);
	for (unsigned int i=0 ; i < m_entities.size() ; i++)
	{
		m_entities[i]->update();
	}
}

void World::addEntity(Entity* entity)
{
	m_entities.push_back(entity);
}

void World::addEntity(PhysicalEntity* entity)
{
    cout << "Adding entity to world " << m_name << endl;
    cpSpaceAddBody(m_space, entity->getBody());
    vector<cpShape*> shapes = entity->getShapes();
    for (unsigned int i=0 ; i < shapes.size() ; i++)
    {
        if (m_space != cpShapeGetSpace(shapes[i]))
            cpSpaceAddShape(m_space, shapes[i]);
    }
	m_entities.push_back(entity);
}

void World::setTileSize(me::Vector2f tileSize)
{
	m_tileSize = tileSize;
}

void World::clear()
{
    for (unsigned int i=0 ; i < m_entities.size() ; i++)
    {
        if (m_entities[i] != NULL)
            delete m_entities[i];
    }
}

string World::getName()
{
    return m_name;
}

me::Entity* World::getEntityAtPos(me::Vector2f pos)
{
	me::Entity* ret(0);
	for (unsigned int i=0 ; i < m_entities.size() ; i++)
	{
		me::Entity* entity = m_entities[i];
		if (entity->getGlobalBounds().contains(pos.x, pos.y))
			ret = entity;
	}
	return ret;
}

me::Vector2f World::getTileSize()
{
	return m_tileSize;
}

cpSpace* World::getSpace()
{
	return m_space;
}

vector<Entity*> World::getEntities()
{
	vector<Entity*> ret;
	ret = m_entities;
	return ret;
}
